#pragma once

#include <iostream>
#include <unistd.h>
#include<memory>
#include"socket.hpp"
#include "log.hpp"
#include <sys/poll.h>
#include<sys/epoll.h>
#include <string>
using namespace logmodule;
using namespace socketmodule;
const static int size = sizeof(fd_set)*8;
const static int  defaultfd = -1;
class EPollServer
{
    
    public:
   EPollServer(int port):_listensock(std::make_unique<Tcpsocket>()),_epollfd(defaultfd)
    {
        _listensock->BuildTcpsocket(port);
       //2创建epoll模型
       //也就是红黑树
       _epollfd = epoll_create(256);
       if(_epollfd<0)
       {
        LOG(loglevel::FATAL)<<"create epollfd error";
        exit(6);
       }
       LOG(loglevel::DEBUG)<<"create epoll success";
       //将listensock设置到内核中
       struct epoll_event ev;
       ev.events = EPOLLIN;//关心读事件
       ev.data.fd = _listensock->Fd();
       int n = epoll_ctl(_epollfd,EPOLL_CTL_ADD,_listensock->Fd(),&ev);
       if(n<0)
       {
        LOG(loglevel::FATAL)<<"add listensockfd error";
       }
         LOG(loglevel::DEBUG)<<"add listensockfd success";

    }
    void accepter()
    {
         inetaddr client;
        int fd = _listensock->accepting(&client);
        if(fd>=0)
        {
            //将新的fd托管到select,放入辅助数组
        }
          struct epoll_event ev;
       ev.events = EPOLLIN;//关心读事件
       ev.data.fd = fd;
       int n = epoll_ctl(_epollfd,EPOLL_CTL_ADD,fd,&ev);
 if(n<0)
       {
        LOG(loglevel::FATAL)<<"add sockfd error";
       }
         LOG(loglevel::DEBUG)<<"add sockfd success";
    }
    void handerevent(int rnum)
    {
        //采用水平触发模式
        for(int i= 0;i<size;i++)
        {
            //循环处理事件
            if(rev[i].events&EPOLLIN)
            {
                //读事件就绪
                 if(rev[i].data.fd == _listensock->Fd())//套接字就绪//新连接到来
                 {
                    accepter();
                 }
            }
        }
        // inetaddr client;
        // int fd = _listensock->accepting(&client);
        // int pos = 0;
        // if(fd>=0)
        // {
        //     //将新的fd托管到select,放入辅助数组
        //     for(;pos< size ;pos++)
        //     {
        //         if(fd_array[pos]==defaultfd)
        //         {
        //             fd_array[pos] = fd;
        //         }
        //     }
        //     if(pos == size)
        //     {
        //         close(fd);
        //     }
        // }
    }
    void Receiver(int pos)
    {
        //读东西不会阻塞
        char buffer[1024];
        ssize_t n = recv(_fds[pos].fd,buffer,sizeof(buffer)-1,0);
        if(n>0)
        {
            buffer[n] = 0;
            std::cout<<""<<std::endl;
        }
        else if(n ==0)
        {
            //客户端退出
            //在辅助数组中去掉
             _fds[pos].fd = defaultfd;
                _fds[pos].events = 0;
                _fds[pos].revents = 0;

            //关闭
            close(_fds[pos].fd);
        }
        else
        {

        }
    }
    void start()
    {
        int timeout = -1;//永久阻塞
        _isrunning = true;
        while(_isrunning)
        {
           int n = epoll_wait(_epollfd,rev,size,timeout);
           switch(n)
           {
            case 0:
            LOG(loglevel::DEBUG)<<"timeout....";
            break;
            case -1:
            LOG(loglevel::FATAL)<<"epoll error....";
            break;
            default:
            handerevent(n);
            break;
           }
        }
        _isrunning = false;
    }
    ~EPollServer()
    {
        _listensock->close();
        if(_epollfd>0)
        {
            close(_epollfd);
        }
    }
    private:
    std::unique_ptr<Socket> _listensock;
    bool _isrunning;
   int _epollfd;
   struct epoll_event rev[size];
};
